#include "StdAfx.h"
#include "Thread.h"
#include "Log.h"

CThread::CThread(void)
	: m_handle(NULL)
	, m_runnable(NULL)
	, m_quitRequested(false)
{
}


CThread::~CThread(void)
{
	join();
}

bool CThread::start(IRunnable * runnable)
{
	ASSERT(runnable != NULL);

	if(m_handle != NULL)
	{
		LOG("Already running");
		return false;
	}

	m_runnable = runnable;
	m_quitRequested = false;

	HANDLE h = (HANDLE)_beginthreadex(
		NULL,				//	security
		0,					//	stack size
		threadFunc,			//	thread function
		(void*)this,		//	argument.
		0,					//	init flags.
		NULL);				//	thread id buffer.

	if(h == NULL)
	{
		LOG("Failed to create thread");
		return false;
	}

	m_handle = h;
	return true;
}

void CThread::join()
{
	if(m_handle != NULL)
	{
		m_quitRequested = true;
		
		WaitForSingleObject(m_handle, INFINITE);
		CloseHandle(m_handle);

		m_handle = NULL;
	}
}

unsigned int WINAPI CThread::threadFunc(void * data)
{
	CThread * thread = (CThread*) data;

	ASSERT(thread != NULL);
	ASSERT(thread->m_runnable != NULL);

	thread->m_runnable->run(thread);

	_endthreadex(0);
	return 0;
}
